﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;

using Castle.DynamicProxy;

using ProjectBase.Core;
using ProjectBase.Core.Service;

using Survey.Filters.Restrictions;

namespace Survey.Filters
{
    [Serializable]
    public class FilterRestrictionManager : IInterceptor
    {
        #region AOP
        public virtual void Intercept(IInvocation invocation)
        {
            if (!DoApplyFilter(invocation))
            {
                invocation.Proceed();
                return;
            }

            // BindFilter
            invocation.Proceed();

            // post processing
            AdjustFilter(invocation);
        }

        protected virtual bool DoApplyFilter(IInvocation invocation)
        {
            // not of our interest
            if (invocation.Arguments.IsEmpty()) // the first (filter) must exists
            {
                return false;
            }

            // is it IAuditable?
            return invocation.Arguments[0] is IFilter;
        }
        #endregion AOP

        protected virtual void AdjustFilter(IInvocation invocation)
        {
            var filter = invocation.Arguments[0] as IFilter;
            Instance.Provider.AdjustFilter(filter);
        }

        #region lazy instance

        // beforefieldinit off
        // see: http://www.yoda.arachsys.com/csharp/singleton.html
        // see: http://www.yoda.arachsys.com/csharp/beforefieldinit.html
        private static class Instance
        {
            // beforefieldinit
            public static readonly IFilterRestrictionProvider Provider;

            static Instance()
            {
                Provider = Factory.CreateInstance<IFilterRestrictionProvider>();

                // Init Handlers
                var handlers = Factory.CreateInstances<IFilterRestrictionHandler>();
                foreach (var handler in handlers)
                {
                    Provider.Add(handler.FilterType, handler);
                }
            }
        }

        #endregion lazy instance
    }
}
